package com.cskaoyan.shopping.service.impl;

import com.cskaoyan.mall.commons.exception.BizException;
import com.cskaoyan.shopping.constants.ShoppingRetCode;
import com.cskaoyan.shopping.converter.CartItemConverter;
import com.cskaoyan.shopping.dal.entitys.Item;
import com.cskaoyan.shopping.dal.persistence.ItemMapper;
import com.cskaoyan.shopping.dto.CartProductDto;
import com.cskaoyan.shopping.form.CartRequest;
import com.cskaoyan.shopping.service.ShoppingCartsService;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;

@Service
public class ShoppingCartsServiceImpl implements ShoppingCartsService {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private ItemMapper itemMapper;

    @Autowired
    private CartItemConverter itemConverter;

    @Override
    public void updateCarts(CartRequest cart) {
        RMap<Object, Object> map = redissonClient.getMap(String.valueOf(cart.getUserId()));
        CartProductDto productDto = (CartProductDto) map.get(cart.getProductId());
        if (productDto == null) {
            throw new BizException(ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getCode(),
                    ShoppingRetCode.CART_PRODUCT_NOT_EXISTS.getMessage());
        }
        productDto.setChecked(cart.getChecked());
        productDto.setProductNum(Long.valueOf(cart.getProductNum()));
        map.put(cart.getProductId(), productDto);
    }

    @Override
    public void deleteCarts(Long userId, Long productId) {
        RMap<Object, Object> map = redissonClient.getMap(String.valueOf(userId));
        map.remove(productId);
    }

    @Override
    public void deleteCartsChecked(Long userId) {
        RMap<Long, CartProductDto> map = redissonClient.getMap(String.valueOf(userId));
        Collection<CartProductDto> products = map.readAllValues();

        Long[] longs = products.stream()
                .filter(t -> "true".equals(t.getChecked()))
                .map(CartProductDto::getProductId)
                .toArray(Long[]::new);

        map.fastRemove(longs);
    }

    @Override
    public void selectAllCarts(CartRequest cart) {
        RMap<Object, CartProductDto> map = redissonClient.getMap(String.valueOf(cart.getUserId()));
        Collection<CartProductDto> products = map.readAllValues();

        for (CartProductDto product : products) {
            product.setChecked(cart.getChecked());
            map.put(product.getProductId(), product);
        }
    }

    @Override
    public void addCarts(CartRequest cart) {
        Long userId = cart.getUserId();
        Long productId = cart.getProductId();
        Integer productNum = cart.getProductNum();

        RMap<Object, CartProductDto> map = redissonClient.getMap(userId.toString());
        CartProductDto product = map.get(productId);

        if (product != null) {
            product.setProductNum(product.getProductNum() + productNum);
            product.setChecked("true");
            map.put(productId, product);
            return;
        }

        Item item = itemMapper.selectByPrimaryKey(productId);
        CartProductDto productDto = itemConverter.item2Dto(item);
        productDto.setProductNum(Long.valueOf(productNum));
        productDto.setChecked("true");
        map.put(productId, productDto);
    }

    @Override
    public List<CartProductDto> queryCarts(Long userId) {
        RMap<Object, CartProductDto> map = redissonClient.getMap(userId.toString());
        Collection<CartProductDto> products = map.readAllValues();
        return (List<CartProductDto>) products;
    }
}
